#ifndef DSPSIMULATOR_LLVMJIT_H
#define DSPSIMULATOR_LLVMJIT_H

#include <memory>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/IR/Function.h>

/**
 * llvm的jit引擎
 */
class LLVMJit {
private:
    std::unique_ptr<llvm::LLVMContext> m_llvmContext;         // llvm上下文
    std::unique_ptr<llvm::Module> m_module;                   // llvm模块
    std::shared_ptr<llvm::IRBuilder<>> m_irBuilder;           // llvm的ir生成器
    std::shared_ptr<llvm::EngineBuilder> m_engineBuilder;     // llvm的jit构建类
    std::shared_ptr<llvm::ExecutionEngine> m_ee;              // llvm的jit执行引擎
public:
    LLVMJit();

    ~LLVMJit() = default;

    /**
     * 初始化一个新的llvm模块
     * @param moduleName 模块名
     */
    void initializeModule(const char *moduleName);

    /**
     * 将当前模块添加到jit执行引擎执行
     */
    void addCurModuleToJit();

    /**
     * 获取llvm的ir生成器
     * @return ir生成器
     */
    std::shared_ptr<llvm::IRBuilder<>> getIrBuilder();

    /**
     * 获取当前的llvm模块(会导致当前jit引擎的当前模块为空)
     * @return 当前的llvm模块
     */
    std::unique_ptr<llvm::Module> extraCurModule();

    /**
     * 获取当前的llvm模块指针
     * @return 当前的llvm模块指针
     */
    llvm::Module *getCurModulePtr();

    /**
     * 获取LLVM上下文指针
     * @return
     */
    llvm::LLVMContext *getLLVMContext();

    /**
     * 获取LLVM执行引擎
     * @return
     */
    std::shared_ptr<llvm::ExecutionEngine> getExecutionEngine();
};

#endif //DSPSIMULATOR_LLVMJIT_H
